﻿using System;
using System.Xml;

namespace Common
{
    /// <summary>
    /// Xml操作帮助类
    /// </summary>
    public static class XmlHelper
    {
        #region 常用
        /// <summary>
        /// 获取节点结合
        /// </summary>
        /// <param name="node"></param>
        /// <param name="xmlPath"></param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodes(this XmlNode node, string xmlPath)
        {
            XmlNodeList result = null;

            XmlNamespaceManager nsmgr = GetXmlNamespaceManager(node);
            if (nsmgr != null)
            {
                xmlPath = "s:" + xmlPath.TrimStart('/').Replace("/", "/s:").Replace("/s:@", "/@");
                result = node.SelectNodes(xmlPath, nsmgr);
            }
            else
            {
                result = node.SelectNodes(xmlPath);
            }

            return result;
        }

        public static string GetValue(this XmlNode node, string xmlPath)
        {
            XmlNode childNode = GetXmlNode(node, xmlPath);
            if (childNode != null)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    return childNode.InnerText;
                }
                else if (childNode.NodeType == XmlNodeType.Attribute)
                {
                    return childNode.Value;
                }
            }

            return "";
        }

        public static void SetValue(this XmlNode node, string xmlPath, string value)
        {
            XmlNode childNode = GetXmlNode(node, xmlPath);
            if (childNode != null)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    childNode.InnerText = value;
                }
                else if (childNode.NodeType == XmlNodeType.Attribute)
                {
                    childNode.Value = value;
                }
            }
        }

        public static void SetValue(this XmlNode node, string xmlPath, object value)
        {
            SetValue(node, xmlPath, Convert.ToString(value));
        }

        private static XmlNamespaceManager GetXmlNamespaceManager(XmlNode node)
        {
            XmlNamespaceManager nsmgr = null;
            XmlDocument doc = null;
            if (node.NodeType == XmlNodeType.Document)
            {
                doc = ((XmlDocument)node);
            }
            else
            {
                doc = node.OwnerDocument;
            }

            if (doc.DocumentElement.NamespaceURI != "")
            {
                nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("s", doc.DocumentElement.NamespaceURI);
            }

            return nsmgr;
        }

        private static XmlNode GetXmlNode(XmlNode node, string xmlPath)
        {
            XmlNamespaceManager nsmgr = GetXmlNamespaceManager(node);
            XmlNode childNode = null;
            if (nsmgr != null)
            {
                //添加带有命名空间前缀的路径写法
                xmlPath = "s:" + xmlPath.TrimStart('/').Replace("/", "/s:").Replace("/s:@", "/@");
                childNode = node.SelectSingleNode(xmlPath, nsmgr);
            }
            else
            {
                childNode = node.SelectSingleNode(xmlPath);
            }

            return childNode;
        }
        #endregion

        #region 很少用
        /// <summary>
        /// 获取节点集合
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <param name="xmlPath"></param>
        /// <param name="namespaceContent"></param>
        /// <returns></returns>
        public static XmlNodeList GetXmlNodesWithNamespace(this XmlNode xmlNode, string xmlPath, string namespaceContent)
        {
            XmlNodeList result = null;

            XmlDocument xmlDocument = null;
            if (xmlNode.NodeType == XmlNodeType.Document)
            {
                xmlDocument = ((XmlDocument)xmlNode);
            }
            else
            {
                xmlDocument = xmlNode.OwnerDocument;
            }
            if (xmlDocument != null)
            {
                XmlNamespaceManager nameSpace = new XmlNamespaceManager(xmlDocument.NameTable);
                nameSpace.AddNamespace("A", namespaceContent);
                xmlPath = "A:" + xmlPath.TrimStart('/').Replace("/", "/A:").Replace("/A:@", "/@");
                result = xmlNode.SelectNodes(xmlPath, nameSpace);
            }

            return result;
        }
        /// <summary>
        /// 获取内容（根元素带命名空间）
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <param name="xmlPath"></param>
        /// <param name="namespaceContent"></param>
        /// <returns></returns>
        public static string GetValueWithNamespace(this XmlNode xmlNode, string xmlPath, string namespaceContent)
        {
            string result = "";

            XmlDocument xmlDocument = null;
            if (xmlNode.NodeType == XmlNodeType.Document)
            {
                xmlDocument = ((XmlDocument)xmlNode);
            }
            else
            {
                xmlDocument = xmlNode.OwnerDocument;
            }
            if (xmlDocument != null)
            {
                XmlNamespaceManager nameSpace = new XmlNamespaceManager(xmlDocument.NameTable);
                nameSpace.AddNamespace("A", namespaceContent);
                xmlPath = "A:" + xmlPath.TrimStart('/').Replace("/", "/A:").Replace("/A:@", "/@");
                XmlNode node = xmlNode.SelectSingleNode(xmlPath, nameSpace);
                if (node != null)
                {
                    if (node.NodeType == XmlNodeType.Element)
                    {
                        result = node.InnerText;
                    }
                    else if (node.NodeType == XmlNodeType.Attribute)
                    {
                        result = node.Value;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// 设置内容（根元素带命名空间）
        /// </summary>
        /// <param name="xmlNode"></param>
        /// <param name="xmlPath"></param>
        /// <param name="value"></param>
        /// <param name="namespaceContent"></param>
        public static void SetVauleWithNamespace(this XmlNode xmlNode, string xmlPath, string value, string namespaceContent)
        {
            XmlDocument xmlDocument = null;
            if (xmlNode.NodeType == XmlNodeType.Document)
            {
                xmlDocument = ((XmlDocument)xmlNode);
            }
            else
            {
                xmlDocument = xmlNode.OwnerDocument;
            }
            if (xmlDocument != null)
            {
                XmlNamespaceManager nameSpace = new XmlNamespaceManager(xmlDocument.NameTable);
                nameSpace.AddNamespace("A", namespaceContent);
                xmlPath = "A:" + xmlPath.TrimStart('/').Replace("/", "/A:").Replace("/A:@", "/@");
                XmlNode node = xmlNode.SelectSingleNode(xmlPath, nameSpace);
                if (node != null)
                {
                    if (node.NodeType == XmlNodeType.Element)
                    {
                        node.InnerText = value;
                    }
                    else if (node.NodeType == XmlNodeType.Attribute)
                    {
                        node.Value = value;
                    }
                }
            }
        }
        #endregion
    }
}